package pers.xdrodger.simple.test.ppt;


import com.spire.presentation.*;
import com.spire.presentation.charts.IChart;

import java.awt.geom.Rectangle2D;
import java.util.*;

public class PptUtil {

    Presentation presentation;

    public static String excelColIndexToStr(int columnIndex) {
        if (columnIndex <= 0) {
            return null;
        }
        String columnStr = "";
        columnIndex--;
        do {
            if (columnStr.length() > 0) {
                columnIndex--;
            }
            columnStr = ((char) (columnIndex % 26 + (int) 'A')) + columnStr;
            columnIndex = (int) ((columnIndex - columnIndex % 26) / 26);
        } while (columnIndex > 0);
        return columnStr;
    }

    public void loadFromPath(String filePath) throws Exception {
        getPpt().loadFromFile(filePath);
    }

    public Presentation getPpt() {
        if (Objects.isNull(presentation)) {
            presentation = new Presentation();
        }
        return presentation;
    }

    public ISlide getFirstSlide(String shapeName) {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            IShape shape = getShape(slide, shapeName);
            if (shape != null) {
                return slide;
            }
        }
        return null;
    }

    public Integer getFirstSlideIndex(String shapeName) {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            IShape shape = getShape(slide, shapeName);
            if (shape != null) {
                return slide.getSlideNumber() - 1;
            }
        }
        return null;
    }

    public IShape getShape(String shapeName) {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            IShape shape = getShape(slide, shapeName);
            if (shape != null) {
                return shape;
            }
        }
        return null;
    }

    public List<IShape> getShapes(ISlide slide, String shapeName) {
        List<IShape> shapes = new LinkedList<>();
        ShapeCollection shapeCollection = slide.getShapes();
        Iterator<IShape> iterator = shapeCollection.iterator();
        while (iterator.hasNext()) {
            IShape shape = iterator.next();
            // 组合图形
            if (shape instanceof GroupShape) {
                IShape innerShape = getShapeFromGroupShape((GroupShape) shape, shapeName);
                if (innerShape != null) {
                    shapes.add(innerShape);
                }
            }
            if (shape.getName().equals(shapeName)) {
                shapes.add(shape);
            }
        }
        return shapes;
    }

    public List<IShape> getShapes(String shapeName) {
        List<IShape> shapes = new ArrayList<>();
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            IShape shape = getShape(slide, shapeName);
            if (shape != null) {
                shapes.add(shape);
            }
        }
        return shapes;
    }

    public IShape getShape(ISlide slide, String shapeName) {
        ShapeCollection shapeCollection = slide.getShapes();
        Iterator<IShape> iterator = shapeCollection.iterator();
        while (iterator.hasNext()) {
            IShape shape = iterator.next();
            // 组合图形
            if (shape instanceof GroupShape) {
                IShape innerShape = getShapeFromGroupShape((GroupShape) shape, shapeName);
                if (innerShape != null) {
                    return innerShape;
                }
            }
            if (shape.getName().equals(shapeName)) {
                return shape;
            }
        }
        return null;
    }

    public IShape getShapeByFuzzyMatch(ISlide slide, String shapeName) {
        ShapeCollection shapeCollection = slide.getShapes();
        Iterator<IShape> iterator = shapeCollection.iterator();
        while (iterator.hasNext()) {
            IShape shape = iterator.next();
            // 组合图形
            if (shape instanceof GroupShape) {
                IShape innerShape = getShapeFromGroupShapeByFuzzyMatch((GroupShape) shape, shapeName);
                if (innerShape != null) {
                    return innerShape;
                }
            }
            if (shape.getName().contains(shapeName)) {
                return shape;
            }
        }
        return null;
    }

    public IShape getShape(ISlide slide, String shapeName, int index) {
        List<IShape> shapes = new LinkedList<>();
        ShapeCollection shapeCollection = slide.getShapes();
        Iterator<IShape> iterator = shapeCollection.iterator();
        while (iterator.hasNext()) {
            IShape shape = iterator.next();
            // 组合图形
            if (shape instanceof GroupShape) {
                IShape innerShape = getShapeFromGroupShape((GroupShape) shape, shapeName);
                if (innerShape != null) {
                    shapes.add(innerShape);
                }
            }
            if (shape.getName().equals(shapeName)) {
                shapes.add(shape);
            }
        }
        return shapes.get(index);
    }

    private IShape getShapeFromGroupShape(GroupShape groupShape, String shapeName) {
        Iterator<IShape> iterator = groupShape.getShapes().iterator();
        while (iterator.hasNext()) {
            IShape innerShape = iterator.next();
            if (innerShape.getName().equals(shapeName)) {
                return innerShape;
            }
            // 内部图形还是租户图形，递归处理
            if (innerShape instanceof GroupShape) {
                IShape shape = getShapeFromGroupShape((GroupShape) innerShape, shapeName);
                if (shape != null) {
                    return shape;
                }
            }
        }
        return null;
    }

    private IShape getShapeFromGroupShapeByFuzzyMatch(GroupShape groupShape, String shapeName) {
        Iterator<IShape> iterator = groupShape.getShapes().iterator();
        while (iterator.hasNext()) {
            IShape innerShape = iterator.next();
            if (innerShape.getName().contains(shapeName)) {
                return innerShape;
            }
            // 内部图形还是租户图形，递归处理
            if (innerShape instanceof GroupShape) {
                IShape shape = getShapeFromGroupShapeByFuzzyMatch((GroupShape) innerShape, shapeName);
                if (shape != null) {
                    return shape;
                }
            }
        }
        return null;
    }

    public IChart getChart(String shapeName) {
        IShape shape = getShape(shapeName);
        if (shape != null) {
            return (IChart) shape;
        }
        return null;
    }

    public IChart getChart(ISlide slide, String shapeName) {
        IShape shape = getShape(slide, shapeName);
        if (shape != null) {
            return (IChart) shape;
        }
        return null;
    }

    public IChart getChart(ISlide slide, String shapeName, int index) {
        IShape shape = getShape(slide, shapeName, index);
        if (shape != null) {
            return (IChart) shape;
        }
        return null;
    }

    public ITable getTable(String shapeName) {
        IShape shape = getShape(shapeName);
        if (shape != null) {
            return (ITable) shape;
        }
        return null;
    }

    public ITable getTable(ISlide slide, String shapeName) {
        IShape shape = getShape(slide, shapeName);
        if (shape != null) {
            return (ITable) shape;
        }
        return null;
    }

    public SlidePicture getSlidePicture(String shapeName) {
        IShape shape = getShape(shapeName);
        if (shape != null) {
            return (SlidePicture) shape;
        }
        return null;
    }

    private String digitToCapitalLetter(int digit) {
        if (digit > 25) {
            return excelColIndexToStr(digit + 1);
        }
        return String.valueOf((char) (digit + 65));
    }

    public void removeShape(String shapeName) {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            IShape shape = getShape(slide, shapeName);
            if (shape != null) {
                slide.getShapes().remove(shape);
                return;
            }
        }
    }

    /**
     * 模糊删除图形
     */
    public void removeAllShapeByFuzzyMatch(String shapeName) {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            IShape shape = getShapeByFuzzyMatch(slide, shapeName);
            if (shape != null) {
                slide.getShapes().remove(shape);
            }
        }
    }


    public void removeShape(ISlide slide, String shapeName) {
        IShape shape = getShape(slide, shapeName);
        if (shape != null) {
            slide.getShapes().remove(shape);
        }
    }

    public void removeShapesExcludeFirst(ISlide slide, String shapeName) {
        List<IShape> shapes = getShapes(slide, shapeName);
        int size = shapes.size();
        for (int i = 0; i < size; i++) {
            IShape shape = shapes.get(i);
            if (i > 0) {
                slide.getShapes().remove(shape);
            }
        }
    }

    public void removeAllShape(String shapeName) {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            IShape shape = getShape(slide, shapeName);
            if (shape != null) {
                slide.getShapes().remove(shape);
            }
        }
    }

    public void removeSlide(String shapeName) {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            IShape shape = getShape(slide, shapeName);
            if (shape != null) {
                getPpt().getSlides().remove(slide);
                return;
            }
        }
    }

    public void removeFirstSlide(String shapeName) {
        ISlide slide = getFirstSlide(shapeName);
        if (slide != null) {
            getPpt().getSlides().remove(slide);
        }
    }

    public void removeAllSlide(String shapeName) {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        for (int i = getPpt().getSlides().getCount() - 1; i >= 0; i--) {
            ISlide slide = getPpt().getSlides().get(i);
            IShape shape = getShape(slide, shapeName);
            if (shape != null) {
                getPpt().getSlides().remove(slide);
            }
        }
    }

    public ISlide copySlide(int slideIndex) throws Exception {
        ISlide slide = getPpt().getSlides().get(slideIndex);
        int index = slideIndex + 1;
        getPpt().getSlides().insert(index, slide);
        return getPpt().getSlides().get(index);
    }

    public IChart horizontalCopyChart(ISlide slide, IChart chart, float margin, String newShapeName) throws Exception {
        Rectangle2D.Double rect1 = new Rectangle2D.Double(chart.getFrame().getRectangle().getX() + margin, chart.getFrame().getRectangle().getY(), chart.getFrame().getRectangle().getWidth(), chart.getFrame().getRectangle().getHeight());
        IChart newChart = slide.getShapes().createChart(chart, rect1, 0);
        newChart.setName(newShapeName);
        return newChart;
    }

    public String savePpt(String fileName) throws Exception {
        //保存文件
        getPpt().saveToFile(fileName, FileFormat.PPTX_2013);
        dispose();
        return fileName;
    }

    public void dispose() {
        getPpt().dispose();
    }

    public void deleteAllNote() {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            NotesSlide notesSlide = slide.getNotesSlide();
            if (notesSlide != null) {
                notesSlide.getNotesTextFrame().getParagraphs().clear();
            }
        }
    }

    public void deleteAllComment() {
        Iterator<ISlide> iterator = getPpt().getSlides().iterator();
        while (iterator.hasNext()) {
            ISlide slide = iterator.next();
            Comment[] comments = slide.getComments();
            if (comments != null) {
                for (Comment comment : comments) {
                    slide.deleteComment(comment);
                }
            }
        }
    }
}
